'''
Created on Apr 22, 2011

@author: david
'''
# python support
from threading import Thread
from time import sleep
import urllib2

# App Engine support
from google.appengine.ext import db

# application support
from model import Profile

DEFAULT_DELAY = 30 * 60   # every 30 minutes

class LoggerHead(Thread):
    '''
    Worker class to read logs and gather changes
    '''

    def __init__(self,url,delay=DEFAULT_DELAY):
        '''
        Constructor
        '''
        Thread.__init__(self)

        self._log = None
        self._delay = delay
        self._run = False    
        self._seturl(url)
        
    def run(self):
        '''
        Threaded loop for running
        periodic log checks 
        '''
        # can not already be running!!!!
        if self._run:
            raise Exception("Already Running...")

        # need a log to run with
        if not self._log:
            raise Exception("No Log Specified")
        
        self._run = True
        tstline = self._log.last
        
        # the loop
        while self._run:
            # open url
            rsp = urllib2.urlopen(self.url)
            
            line1 = rsp.readline().strip()
            if str(line1) != str(tstline):
                # create change object
                lc = LogChange(self, "%s\n" % line1)

                # read in all new lines
                for line in rsp:
                    # break on match
                    if str(line) == str(tstline):
                        break
                    
                    # add to change lost
                    lc.addLine(line)
                
                # fire notifications
                lc.notify()
                
                # update log watch
                self._log.last = line1
                self._log.put()
                
            sleep(self._delay)
            
    def stopPlease(self):
        self._run = False
    
    # Log Property 
    # (r/o property- use URL to set)
    def _getlog(self):
        return self._log
    log = property(_getlog)
    
    # URL Property
    def _geturl(self):
        return self._log.url
    def _seturl(self, url):
        if self._run:
            raise Exception("Cannot set log after starting!")
        
        self._log = db.GqlQuery("Select * from Log where url='%s'" % url).get()
        
    url = property(_geturl,_seturl)
    
    # delay property
    def _getdelay(self):
        return self._delay
    def _setdelay(self,secs):
        self._delay = secs
    
    delay = property(_getdelay,_setdelay)
     
class ChangeNotification(Thread):
    def __init__(self, lc):
        Thread.__init__(self)
        self._lc = lc
        
    def run(self):
        """
        First round, just send change listing 
        to all registered users.
        TODO: Be selective
        """
        # get change text
        chgtxt = self._lc.getChanges()
        
        # get set of all profiles
        pSet = Profile.all()
        for prof in pSet:
            # send changes to each profile
            self._send(chgtxt,prof.address)
                
    def _send(self,txt, addr):
        """
        send text to email addr
        """
        pass
        
class LogChange(object):
    '''
    Captures and distributes log change
    '''
    def __init__(self,lh, line1):
        self._lh = lh
        self._changetext = [line1]
    
    def addLine(self,text):
        'Append text to changes'
        self._changetext.append(text)
        
    def notify(self):
        """
        Send changes to all monitoring 
        emails.
        """
        cn = ChangeNotification(self)
        cn.start()
    
    def getChanges(self):
        return self._changetext